package titt.io.reader.head;

import java.util.ArrayList;

import titt.TITTValues;
import titt.head.HTTPHead;
import titt.head.HeadFactory;
import titt.head.Header;
import titt.io.socket.in.TITTInputStream;
import titt.util.Bytes;

public class HeadReaderImpl implements HeadReader{

	private final TITTInputStream in;
	
	public HeadReaderImpl(TITTInputStream in) {
		this.in = in;
	}
	
	@Override
	public HTTPHead readHead(boolean waitForStatus) throws Exception {
		String status = null;
		ArrayList<Header> headers = new ArrayList<Header>();
		boolean statusRead = !waitForStatus;

		byte[] inp;
		while((inp = in.readLine()) != null && (inp.length > 0 || !statusRead))
			if(inp.length > 0)
				if(startsWith(inp, TITTValues.GET_BYTES, TITTValues.POST_BYTES, TITTValues.HTTP_BYTES, TITTValues.OPTIONS_BYTES)) {
					status = Bytes.asString(inp);
					statusRead = true;
				}
				else {
					String line = Bytes.asString(inp);
					int i = line.indexOf(": ");
					if(i > -1) 
						headers.add(new Header(line.substring(0, i), Bytes.copy(inp, i+2, inp.length-(i+2))));
				}
			
		return HeadFactory.createHead(status, headers.toArray(new Header[headers.size()]));
	}

	private boolean startsWith(byte[] val, byte[]... pres) {
		for(byte[] pre : pres) {
			if(startsWith(val, pre)) return true;
		}
		return false;
	}

	private boolean startsWith(byte[] val, byte[] pre) {
		if(pre.length > val.length) return false;
		for(int i = 0; i < pre.length; i++) {
			if(val[i] != pre[i]) return false;
		}
		return true;
	}

	@Override
	public HTTPHead readHead() throws Exception {
		return readHead(true);
	}

}
